package com.xci.core.helper;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.xci.core.base.GMap;
import com.xci.core.base.RestMessage;
import com.xci.core.internal.Const;
import eu.bitwalker.useragentutils.UserAgent;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.RequestContext;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.*;
import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * Web 帮助类
 * @author 吕艳阳
 */
public class WebHelper {
    /**
     * 判断文件是否是图片类型
     */
    public static boolean isImage(InputStream imageFile) {
        try {
            Image img = ImageIO.read(imageFile);
            return img != null && img.getWidth(null) > 0 && img.getHeight(null) > 0;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 判断请求是否为ajax请求
     */
    public static boolean isAjax(HttpServletRequest request) {
        String type = request.getHeader("X-Requested-With");
        if (Helper.isBlank(type)) {
            type = request.getParameter("X-Requested-With");
        }
        return Helper.isNotBlank(type) && "XMLHttpRequest".equals(type);
    }

    /**
     * 判断请求是否为app请求
     */
    public static boolean isApp(HttpServletRequest request) {
        String type = request.getHeader("X-Requested-With");
        if (Helper.isBlank(type)) {
            type = request.getParameter("X-Requested-With");
        }
        return Helper.isNotBlank(type) && "AppHttpRequest".equals(type);
    }

    /**
     * 是否是报表设计模式
     */
    public static boolean isReportDesignMode() {
        String mode = WebHelper.getParameter("mode");
        return Helper.isNotBlank(mode) && mode.equals("design");
    }

    /**
     * 是否是报表预览模式
     */
    public static boolean isReportPreviewMode() {
        String mode = WebHelper.getParameter("mode");
        return Helper.isNotBlank(mode) && mode.equals("preview");
    }

    /**
     * 是否是报表打印模式
     */
    public static boolean isReportPrintMode() {
        String mode = WebHelper.getParameter("mode");
        return Helper.isNotBlank(mode) && mode.equals("print");
    }

    /**
     * 是否是报表查看模式
     */
    public static boolean isReportViewMode() {
        String mode = WebHelper.getParameter("mode");
        return Helper.isNotBlank(mode) && mode.equals("view");
    }

    /**
     * 输出Json对象
     * @param data 输出的Json对象
     * @throws IOException IO异常
     */
    public static void writeJson(RestMessage data) throws IOException {
        HttpServletResponse response = getResponse();
        response.setStatus(HttpServletResponse.SC_OK);
        response.setHeader("Content-type", "application/json;charset=UTF-8");
        response.getWriter().write(JsonHelper.serialize(data));
    }

    /**
     * 获取浏览器信息
     */
    public static String getBrowserInfo(HttpServletRequest request) {
        if (request.getHeader("User-Agent") != null) {
            UserAgent agent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
            if (agent.getOperatingSystem() == null || agent.getBrowserVersion() == null) {
                return "";
            }
            return StrUtil.format("{} {} {}", agent.getOperatingSystem().getName(), agent.getBrowser().getName(), agent.getBrowserVersion().getMajorVersion());
        }
        return "";
    }

    /**
     * 获取站点Url信息
     */
    public static String getSiteUrl() {
        HttpServletRequest request = getRequest();
        if (request != null) {
            //http
            String scheme = request.getScheme();
            //localhost
            String serverName = request.getServerName();
            //8080
            int serverPort = request.getServerPort();
            if (serverPort == 80) {
                return Helper.format("{}://{}", scheme, serverName);
            }
            return Helper.format("{}://{}:{}", scheme, serverName, serverPort);
        }
        return Const.EMPTY;
    }

    /**
     * 获取完整Url信息
     */
    public static String getSiteFullUrl(String virtualUrl) {
        HttpServletRequest request = getRequest();
        if (request != null) {
            String rootUrl = getSiteUrl();
            if (!virtualUrl.startsWith("/")) {
                virtualUrl = "/" + virtualUrl;
            }
            return Helper.format("{}{}{}", rootUrl, request.getContextPath(), virtualUrl);
        }
        return Const.EMPTY;
    }

    /**
     * 获取Web项目下的web root路径
     * @return web root路径
     * @since 4.0.13
     */
    public static File getWebRoot() {
        return FileUtil.getWebRoot();
    }

    /**
     * 获得文件的扩展名，扩展名不带“.”
     * @param fileName 文件名
     * @return 扩展名
     */
    public static String extName(String fileName) {
        return FileUtil.extName(fileName);
    }

    /**
     * 返回主文件名
     * @param fileName 完整文件名
     * @return 主文件名
     */
    public static String mainName(String fileName) {
        return FileUtil.mainName(fileName);
    }

    /**
     * 获取请求参数键值对
     */
    public static GMap getRequestParamMap() {
        HttpServletRequest request = getRequest();
        GMap map = new GMap();
        Enumeration<String> es = request.getParameterNames();
        while (es.hasMoreElements()) {
            String val = es.nextElement();
            map.put(val, request.getParameter(val));
        }
        return map;
    }

    public static ServletRequestAttributes getRequestAttributes() {
        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        return (ServletRequestAttributes) attributes;
    }

    /**
     * 获取request
     */
    public static HttpServletRequest getRequest() {
        return getRequestAttributes().getRequest();
    }

    /**
     * 获取response
     */
    public static HttpServletResponse getResponse() {
        return getRequestAttributes().getResponse();
    }

    /**
     * 获取session
     */
    public static HttpSession getSession() {
        return getRequestAttributes().getRequest().getSession();
    }

    /**
     * 获取String参数
     */
    public static String getParameter(String name) {
        return getRequest().getParameter(name);
    }

    /**
     * 获取String参数
     */
    public static String getParameter(String name, String defaultValue) {
        return Convert.toStr(getRequest().getParameter(name), defaultValue);
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name) {
        return Convert.toInt(getRequest().getParameter(name));
    }

    /**
     * 获取Integer参数
     */
    public static Integer getParameterToInt(String name, Integer defaultValue) {
        return Convert.toInt(getRequest().getParameter(name), defaultValue);
    }

    public static Map<String, Object> convertDataMap(HttpServletRequest request) {
        Map<String, String[]> properties = request.getParameterMap();
        Map<String, Object> returnMap = new HashMap<String, Object>();
        Iterator<?> entries = properties.entrySet().iterator();
        Map.Entry<?, ?> entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry<?, ?>) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (int i = 0; i < values.length; i++) {
                    value = values[i] + ",";
                }
                value = value.substring(0, value.length() - 1);
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    /**
     * 检测浏览器兼容性
     * @return 不存在兼容性返回true
     */
    public static boolean checkBrowserCompatibility() {
        String userAgent = WebHelper.getRequest().getHeader("User-Agent");
        if (Helper.isBlank(userAgent)) {
            return false;
        }
        UserAgent agent = UserAgent.parseUserAgentString(userAgent);
        String name = "";
        int version = 0;
        if (agent.getBrowser() != null) {
            name = agent.getBrowser().getName();
        }
        if (agent.getBrowserVersion() != null) {
            version = Integer.parseInt(agent.getBrowserVersion().getMajorVersion());
        }
        boolean result = ((name.contains("Chrome") && version >= 40) || (name.contains("Firefox") && version >= 40) || (name.contains("Opera") && version >= 40) || (name.contains(
                "Safari") && version >= 8) || (name.contains("Edge") && version >= 10) || (name.contains("Internet Explorer") && version >= 11));
        return result;
    }

    /**
     * 将URL的参数和body参数合并
     */
    public static SortedMap<String, String> getAllParams(HttpServletRequest request) throws IOException {
        SortedMap<String, String> result = new TreeMap<>();
        // 获取URL上的参数
        getUrlParams(request, result);
        // 获取body参数
        getAllRequestParam(request, result);
        return result;
    }

    /**
     * 获取 Body 参数
     */
    public static void getAllRequestParam(final HttpServletRequest request, SortedMap<String, String> result)
            throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
        String str = "";
        StringBuilder wholeStr = new StringBuilder();
        // 一行一行的读取body体里面的内容；
        while ((str = reader.readLine()) != null) {
            wholeStr.append(str);
        }
        wholeStr.trimToSize();
        String s = wholeStr.toString();
        if (!StringUtils.isEmpty(s)) {
            // // 转化成json对象
            // Map<String, String> allRequestParam = JsonHelper.deserialize(s, Map.class);
            // // 将URL的参数和body参数进行合并
            // for (Map.Entry entry : allRequestParam.entrySet()) {
            //     result.put((String)entry.getKey(), (String)entry.getValue());
            // }
        }
    }

    /**
     * 获取url参数
     */
    public static void getUrlParams(HttpServletRequest request, SortedMap<String, String> result) {
        String param = "";
        String urlParam = request.getQueryString();
        if (urlParam != null) {
            param = URLDecoder.decode(urlParam, StandardCharsets.UTF_8);
        }
        String[] params = param.split("&");
        for (String s : params) {
            int index = s.indexOf("=");
            if (index != -1) {
                result.put(s.substring(0, index), s.substring(index + 1));
            }
        }
    }

    /**
     * 获取请求上下文
     * @return 返回请求上下文
     */
    public static String getContextPath() {
        return WebHelper.getRequest().getContextPath();
    }

    /**
     * 获取请求上下文绝对路径
     * @param httpServletRequest 请求对象
     * @param relativeUrl        指定的路径
     * @return 返回请求上下文绝对路径
     */
    public static String getContextUrl(HttpServletRequest httpServletRequest, String relativeUrl) {
        RequestContext requestContext = new RequestContext(httpServletRequest);
        return requestContext.getContextUrl(relativeUrl);
    }

    /**
     * 获取请求上下文绝对路径
     * @param httpServletRequest 请求对象
     * @param relativeUrl        指定的路径
     * @param params             传递的参数
     * @return 返回请求上下文绝对路径
     */
    public static String getContextUrl(HttpServletRequest httpServletRequest, String relativeUrl, Map<String, ?> params) {
        RequestContext requestContext = new RequestContext(httpServletRequest);
        return requestContext.getContextUrl(relativeUrl, params);
    }
}